/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package IoTools;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYDotRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 *
 * @author pipboy2000
 */
public class AnalyserCellByTime {
    // will stock results
    SimResult currentResult = new SimResult();
    static int dim = 0;     // dimension of solution
    static int length = 0;  // lenght of solution

    /**
     * constructor
     */
    public AnalyserCellByTime(String path, String name, Boolean writeToPNG) {
        try {

            /* init vars */
            String file = path + name + ".txt";
            String inputLine;   // String input variable
            double inputDbl;   // double to convert above String to 
            StringTokenizer tokenizer;   // used to tokenize an input line at addedLines time
            String inputStr;   // addedLines token from input line

            /* get solution dimension (num of equation -1) */
            dim = AnalyserTools.computeSolDimension(file);
            /*get number of lines */
            length = AnalyserTools.computeSolLength(file);

            /* init cellSeries and cellDataset */
            XYSeries cellSeries[] = null;
            XYSeries spikeSeries[] = null;
            XYSeriesCollection cellDataset[] = null;
            XYSeriesCollection spikeDataset = new XYSeriesCollection();

            cellSeries = new XYSeries[dim];
            spikeSeries = new XYSeries[dim];
            cellDataset = new XYSeriesCollection[dim];
            
            for (int j = 0; j < dim; j++) {
                cellSeries[j] = new XYSeries("Plot" + j);
                spikeSeries[j] = new XYSeries("Spikes" + j);
                cellDataset[j] = new XYSeriesCollection();
            }
            
            // change names of main cellSeries
            cellSeries[0] = new XYSeries("N1");
            cellSeries[3] = new XYSeries("N2");
            cellSeries[6] = new XYSeries("N3");
            cellSeries[9] = new XYSeries("N4");
            cellSeries[12] = new XYSeries("AS");

            // fill cellSeries with file content
            FileReader reader = new FileReader(file);   // initialize readers
            BufferedReader in = new BufferedReader(reader);
            double t = 0.0; // time vector
            int addedLines = 0; // number of datas used for plot

            // spikes test (s*fl1 = flag for spike of neuron '*' superior to 1.0 )
            boolean s1fl1 = false, s2fl1 = false, s3fl1 = false, s4fl1 = false, scfl1 = false;

            // takes line by line
            for (int i = 0; i < length; i++) {
                inputLine = in.readLine();  // stock addedLines line
                tokenizer = new StringTokenizer(inputLine, " ");    // parse this line by string
                for (int d = 0; d < dim; d++) {   // for all the dimensions
                    inputStr = tokenizer.nextToken();   // get next token from tokenizer
                    inputDbl = Double.parseDouble(inputStr);   // convert it to double
                    /* count spikes */
                    if (d == 1) {   // for v1
                        if (inputDbl > 1) {
                            s1fl1 = true;
                        }
                        if ((inputDbl <= 1) && (s1fl1)) {
                            currentResult.UpN1Spikes(i);
                            spikeSeries[0].add(i, 1);
                            s1fl1 = false;
                        }
                    }
                    if (d == 4) {   // for v2
                        if (inputDbl > 1) {
                            s2fl1 = true;
                        }
                        if ((inputDbl <= 1) && (s2fl1)) {
                            currentResult.UpN2Spikes(i);
                            spikeSeries[3].add(i, 2);
                            s2fl1 = false;
                        }
                    }
                    if (d == 7) {   // for v3
                        if (inputDbl > 1) {
                            s3fl1 = true;
                        }
                        if ((inputDbl <= 1) && (s3fl1)) {
                            currentResult.UpN3Spikes(i);
                            spikeSeries[6].add(i, 3);
                            s3fl1 = false;
                        }
                    }
                    if (d == 10) {   // for v4
                        if (inputDbl > 1) {
                            s4fl1 = true;
                        }
                        if ((inputDbl <= 1) && (s4fl1)) {
                            currentResult.UpN4Spikes(i);
                            spikeSeries[9].add(i, 4);
                            s4fl1 = false;
                        }
                    }
                    if (d == 13) {   // for c
                        if (inputDbl > 1) {
                            scfl1 = true;
                        }
                        if ((inputDbl <= 1) && (scfl1)) {
                            currentResult.UpAstroSpikes(i);
                            spikeSeries[12].add(i, 0);
                            scfl1 = false;
                        }
                    }

                    /* fill cellSeries */
                    if ((i % 20) == 0) {  
                        if (d == 0) {  //dim 0 = t
                            t = inputDbl;
                        } else {
                            // ! cellSeries d-1 
                            cellSeries[d - 1].add(t, inputDbl); // put the cell "voltage" (inputDbl) in the position i ( = "time") of the cellSeries
                            
                        }
                    }
                    addedLines++;
                }
            }

            reader.close();   // close reader

            if (writeToPNG) {
                
                // fill cellDatasets with cellSeries
                for (int j = 0; j < dim; j++) {
                    cellDataset[j].addSeries(cellSeries[j]);
                }
                // Built Chart for plotting each cell
                AnalyserTools.JFreeChartBuilder(path, name, "v1", "t", "mV", cellDataset[0]);
                AnalyserTools.JFreeChartBuilder(path, name, "v2", "t", "mV", cellDataset[3]);
                AnalyserTools.JFreeChartBuilder(path, name, "v3", "t", "mV", cellDataset[6]);
                AnalyserTools.JFreeChartBuilder(path, name, "v4", "t", "mV", cellDataset[9]);
                AnalyserTools.JFreeChartBuilder(path, name, "c", "t", "mV", cellDataset[12]);
                /* and a final combined one */
                XYItemRenderer renderer[] = new XYLineAndShapeRenderer[5];
                for (int j = 0; j < 5; j++) {
                    renderer[j] = new XYLineAndShapeRenderer(true, false);
                }
                // set styles
                renderer[0].setSeriesPaint(0, new Color(60, 90, 255));
                renderer[1].setSeriesPaint(0, new Color(60, 130, 255));
                renderer[2].setSeriesPaint(0, new Color(60, 170, 255));
                renderer[3].setSeriesPaint(0, new Color(255, 130, 60));
                renderer[4].setSeriesPaint(0, Color.DARK_GRAY);
                // set axis labels
                NumberAxis rangeAxis0 = new NumberAxis("n1");
                NumberAxis rangeAxis1 = new NumberAxis("n2");
                NumberAxis rangeAxis2 = new NumberAxis("n3");
                NumberAxis rangeAxis3 = new NumberAxis("n4");
                NumberAxis rangeAxis4 = new NumberAxis("Astrocyte");
                // add subplots
                XYPlot subplot0 = new XYPlot(cellDataset[0], null, rangeAxis0, renderer[0]);
                XYPlot subplot1 = new XYPlot(cellDataset[3], null, rangeAxis1, renderer[1]);
                XYPlot subplot2 = new XYPlot(cellDataset[6], null, rangeAxis2, renderer[2]);
                XYPlot subplot3 = new XYPlot(cellDataset[9], null, rangeAxis3, renderer[3]);
                XYPlot subplot4 = new XYPlot(cellDataset[12], null, rangeAxis4, renderer[4]);
                // finaly put all together
                CombinedDomainXYPlot combiPlot = new CombinedDomainXYPlot(new NumberAxis("time"));
                combiPlot.setGap(5);
                combiPlot.add(subplot0);
                combiPlot.add(subplot1);
                combiPlot.add(subplot2);
                combiPlot.add(subplot3);
                combiPlot.add(subplot4);
                JFreeChart combiChart = new JFreeChart("Summary of neuron behaviouring with " + name, JFreeChart.DEFAULT_TITLE_FONT, combiPlot, true);
                AnalyserTools.PNGExporter(path, name + "_summary", combiChart);
                // fill spikeDataSet
                spikeDataset.addSeries(spikeSeries[0]);
                spikeDataset.addSeries(spikeSeries[3]);
                spikeDataset.addSeries(spikeSeries[6]);
                spikeDataset.addSeries(spikeSeries[9]);
                spikeDataset.addSeries(spikeSeries[12]);
                //style
                XYDotRenderer spikesRenderer = new XYDotRenderer();
                spikesRenderer.setSeriesPaint(0, new Color(60, 90, 255));
                spikesRenderer.setSeriesPaint(1, new Color(60, 130, 255));
                spikesRenderer.setSeriesPaint(2, new Color(60, 170, 255));
                spikesRenderer.setSeriesPaint(3, new Color(255, 130, 60));
                spikesRenderer.setSeriesPaint(4, Color.DARK_GRAY);
                
                NumberAxis cellAxis = new NumberAxis("cell");
                NumberAxis timeAxis = new NumberAxis("time");
                 
                XYPlot spikeFinal = new XYPlot(spikeDataset, cellAxis, timeAxis, spikesRenderer);
                // within a JFreeChart
                 JFreeChart spikeChart = new JFreeChart("Spiking synchonisation " + name, JFreeChart.DEFAULT_TITLE_FONT, spikeFinal, true);
                AnalyserTools.PNGExporter(path, name + "_spikeSync", spikeChart);
                
                
                
            }// end if(writeToPNG)

            // out results to console
            System.out.println("s1:" + currentResult.N1Spikes().size() +
                    " s2:" + currentResult.N2Spikes().size() +
                    " s3:" + currentResult.N3Spikes().size() +
                    " s4:" + currentResult.N4Spikes().size() +
                    " sc:" + currentResult.AstroSpikes().size() );

        //catch exeptions
        } catch (FileNotFoundException ex) {
            Logger.getLogger(AnalyserCellByTime.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(AnalyserCellByTime.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Permit to extract results of cells spikes for a (Gamma, Delta) couple
     * @return an SimResult(int N1, int N2, int N3, int N4,int AS, double G, double D )
     */
    public SimResult getResult() {
        return currentResult;
    }
    
    /**
     * 
     * @return
     */
    public int isEpileptic() {
        //if "epileptic effect"
        if ((currentResult.N2Spikes().size() > (10 * currentResult.N1Spikes().size() )) ||
                (currentResult.N3Spikes().size() > (10 * currentResult.AstroSpikes().size() )) ||
                (currentResult.N4Spikes().size() > (10 * currentResult.N1Spikes().size() ))) {
            return 3;
        // if boost of the "passive" subnetwork : "normal++ effect"
        } else if (currentResult.N3Spikes().size() > 1) {
            return 2;
        // if boost the n2 : "normal effect"
        } else if (currentResult.N2Spikes().size() > 6) {
            return 1;
        // IF ASTROCYTE HAV NO EFFECT
        } else {
            return 0;
        }
    }
    
    
    /**
     * 
     */
}







